import { useEffect, useRef, useCallback } from 'react'

/**
 * 手势识别 Hook
 * 支持：滑动、缩放、长按、双击等手势
 */

/**
 * 滑动手势 Hook
 * @param {Object} options - 配置选项
 * @returns {Object} - 绑定到元素的 props
 */
export function useSwipe(options = {}) {
  const {
    onSwipeLeft,
    onSwipeRight,
    onSwipeUp,
    onSwipeDown,
    threshold = 50, // 最小滑动距离
    timeout = 300, // 最大滑动时间
  } = options

  const touchStart = useRef({ x: 0, y: 0, time: 0 })
  const touchEnd = useRef({ x: 0, y: 0, time: 0 })

  const handleTouchStart = useCallback((e) => {
    const touch = e.touches[0]
    touchStart.current = {
      x: touch.clientX,
      y: touch.clientY,
      time: Date.now(),
    }
  }, [])

  const handleTouchEnd = useCallback((e) => {
    const touch = e.changedTouches[0]
    touchEnd.current = {
      x: touch.clientX,
      y: touch.clientY,
      time: Date.now(),
    }

    const deltaX = touchEnd.current.x - touchStart.current.x
    const deltaY = touchEnd.current.y - touchStart.current.y
    const deltaTime = touchEnd.current.time - touchStart.current.time

    // 检查是否超时
    if (deltaTime > timeout) return

    const absX = Math.abs(deltaX)
    const absY = Math.abs(deltaY)

    // 水平滑动
    if (absX > absY && absX > threshold) {
      if (deltaX > 0 && onSwipeRight) {
        onSwipeRight({ deltaX, deltaY, deltaTime })
      } else if (deltaX < 0 && onSwipeLeft) {
        onSwipeLeft({ deltaX, deltaY, deltaTime })
      }
    }
    // 垂直滑动
    else if (absY > absX && absY > threshold) {
      if (deltaY > 0 && onSwipeDown) {
        onSwipeDown({ deltaX, deltaY, deltaTime })
      } else if (deltaY < 0 && onSwipeUp) {
        onSwipeUp({ deltaX, deltaY, deltaTime })
      }
    }
  }, [onSwipeLeft, onSwipeRight, onSwipeUp, onSwipeDown, threshold, timeout])

  return {
    onTouchStart: handleTouchStart,
    onTouchEnd: handleTouchEnd,
  }
}

/**
 * 缩放手势 Hook (双指捏合)
 * @param {Object} options - 配置选项
 * @returns {Object} - 绑定到元素的 props
 */
export function usePinch(options = {}) {
  const {
    onPinchStart,
    onPinch,
    onPinchEnd,
    minScale = 0.5,
    maxScale = 3,
  } = options

  const initialDistance = useRef(0)
  const currentScale = useRef(1)
  const isPinching = useRef(false)

  const getDistance = (touch1, touch2) => {
    const dx = touch2.clientX - touch1.clientX
    const dy = touch2.clientY - touch1.clientY
    return Math.sqrt(dx * dx + dy * dy)
  }

  const handleTouchStart = useCallback((e) => {
    if (e.touches.length === 2) {
      isPinching.current = true
      initialDistance.current = getDistance(e.touches[0], e.touches[1])
      
      if (onPinchStart) {
        onPinchStart({ scale: currentScale.current })
      }
    }
  }, [onPinchStart])

  const handleTouchMove = useCallback((e) => {
    if (e.touches.length === 2 && isPinching.current) {
      e.preventDefault() // 防止页面缩放
      
      const distance = getDistance(e.touches[0], e.touches[1])
      const scale = distance / initialDistance.current
      const newScale = Math.max(minScale, Math.min(maxScale, currentScale.current * scale))
      
      if (onPinch) {
        onPinch({ 
          scale: newScale, 
          delta: scale,
          center: {
            x: (e.touches[0].clientX + e.touches[1].clientX) / 2,
            y: (e.touches[0].clientY + e.touches[1].clientY) / 2,
          }
        })
      }
      
      initialDistance.current = distance
      currentScale.current = newScale
    }
  }, [onPinch, minScale, maxScale])

  const handleTouchEnd = useCallback((e) => {
    if (isPinching.current && e.touches.length < 2) {
      isPinching.current = false
      
      if (onPinchEnd) {
        onPinchEnd({ scale: currentScale.current })
      }
    }
  }, [onPinchEnd])

  return {
    onTouchStart: handleTouchStart,
    onTouchMove: handleTouchMove,
    onTouchEnd: handleTouchEnd,
  }
}

/**
 * 长按手势 Hook
 * @param {Function} callback - 长按回调
 * @param {number} duration - 长按时长 (ms)
 * @returns {Object} - 绑定到元素的 props
 */
export function useLongPress(callback, duration = 500) {
  const timeout = useRef(null)
  const target = useRef(null)

  const start = useCallback((e) => {
    target.current = e.target
    timeout.current = setTimeout(() => {
      callback(e)
    }, duration)
  }, [callback, duration])

  const clear = useCallback(() => {
    if (timeout.current) {
      clearTimeout(timeout.current)
      timeout.current = null
    }
  }, [])

  return {
    onTouchStart: start,
    onTouchEnd: clear,
    onTouchMove: clear,
    onMouseDown: start,
    onMouseUp: clear,
    onMouseLeave: clear,
  }
}

/**
 * 双击手势 Hook
 * @param {Function} callback - 双击回调
 * @param {number} delay - 双击间隔 (ms)
 * @returns {Object} - 绑定到元素的 props
 */
export function useDoubleTap(callback, delay = 300) {
  const lastTap = useRef(0)

  const handleTap = useCallback((e) => {
    const now = Date.now()
    const timeSinceLastTap = now - lastTap.current

    if (timeSinceLastTap < delay && timeSinceLastTap > 0) {
      callback(e)
      lastTap.current = 0
    } else {
      lastTap.current = now
    }
  }, [callback, delay])

  return {
    onTouchEnd: handleTap,
    onClick: handleTap,
  }
}

/**
 * 拖拽手势 Hook
 * @param {Object} options - 配置选项
 * @returns {Object} - 绑定到元素的 props
 */
export function useDrag(options = {}) {
  const {
    onDragStart,
    onDrag,
    onDragEnd,
    axis = 'both', // 'x' | 'y' | 'both'
  } = options

  const isDragging = useRef(false)
  const startPosition = useRef({ x: 0, y: 0 })
  const currentPosition = useRef({ x: 0, y: 0 })

  const handleStart = useCallback((e) => {
    isDragging.current = true
    const clientX = e.touches ? e.touches[0].clientX : e.clientX
    const clientY = e.touches ? e.touches[0].clientY : e.clientY
    
    startPosition.current = { x: clientX, y: clientY }
    currentPosition.current = { x: clientX, y: clientY }
    
    if (onDragStart) {
      onDragStart({ x: clientX, y: clientY })
    }
  }, [onDragStart])

  const handleMove = useCallback((e) => {
    if (!isDragging.current) return
    
    e.preventDefault()
    
    const clientX = e.touches ? e.touches[0].clientX : e.clientX
    const clientY = e.touches ? e.touches[0].clientY : e.clientY
    
    let deltaX = clientX - currentPosition.current.x
    let deltaY = clientY - currentPosition.current.y
    
    // 根据轴限制移动
    if (axis === 'x') deltaY = 0
    if (axis === 'y') deltaX = 0
    
    currentPosition.current = { x: clientX, y: clientY }
    
    if (onDrag) {
      onDrag({ 
        x: clientX, 
        y: clientY,
        deltaX,
        deltaY,
        totalDeltaX: clientX - startPosition.current.x,
        totalDeltaY: clientY - startPosition.current.y,
      })
    }
  }, [onDrag, axis])

  const handleEnd = useCallback((e) => {
    if (!isDragging.current) return
    
    isDragging.current = false
    
    if (onDragEnd) {
      onDragEnd({
        totalDeltaX: currentPosition.current.x - startPosition.current.x,
        totalDeltaY: currentPosition.current.y - startPosition.current.y,
      })
    }
  }, [onDragEnd])

  return {
    onTouchStart: handleStart,
    onTouchMove: handleMove,
    onTouchEnd: handleEnd,
    onMouseDown: handleStart,
    onMouseMove: handleMove,
    onMouseUp: handleEnd,
  }
}

/**
 * 组合手势 Hook
 * 同时支持多种手势
 * @param {Object} handlers - 手势处理器集合
 * @returns {Object} - 绑定到元素的 props
 */
export function useGestures(handlers = {}) {
  const swipeHandlers = useSwipe({
    onSwipeLeft: handlers.onSwipeLeft,
    onSwipeRight: handlers.onSwipeRight,
    onSwipeUp: handlers.onSwipeUp,
    onSwipeDown: handlers.onSwipeDown,
  })

  const pinchHandlers = usePinch({
    onPinchStart: handlers.onPinchStart,
    onPinch: handlers.onPinch,
    onPinchEnd: handlers.onPinchEnd,
    minScale: handlers.minScale,
    maxScale: handlers.maxScale,
  })

  const dragHandlers = useDrag({
    onDragStart: handlers.onDragStart,
    onDrag: handlers.onDrag,
    onDragEnd: handlers.onDragEnd,
    axis: handlers.axis,
  })

  // 合并所有手势处理器
  const combinedHandlers = {}
  
  // 合并 touchStart
  if (swipeHandlers.onTouchStart || pinchHandlers.onTouchStart || dragHandlers.onTouchStart) {
    combinedHandlers.onTouchStart = (e) => {
      swipeHandlers.onTouchStart?.(e)
      pinchHandlers.onTouchStart?.(e)
      dragHandlers.onTouchStart?.(e)
    }
  }

  // 合并 touchMove
  if (pinchHandlers.onTouchMove || dragHandlers.onTouchMove) {
    combinedHandlers.onTouchMove = (e) => {
      pinchHandlers.onTouchMove?.(e)
      dragHandlers.onTouchMove?.(e)
    }
  }

  // 合并 touchEnd
  if (swipeHandlers.onTouchEnd || pinchHandlers.onTouchEnd || dragHandlers.onTouchEnd) {
    combinedHandlers.onTouchEnd = (e) => {
      swipeHandlers.onTouchEnd?.(e)
      pinchHandlers.onTouchEnd?.(e)
      dragHandlers.onTouchEnd?.(e)
    }
  }

  // 合并鼠标事件
  if (dragHandlers.onMouseDown) {
    combinedHandlers.onMouseDown = dragHandlers.onMouseDown
  }
  if (dragHandlers.onMouseMove) {
    combinedHandlers.onMouseMove = dragHandlers.onMouseMove
  }
  if (dragHandlers.onMouseUp) {
    combinedHandlers.onMouseUp = dragHandlers.onMouseUp
  }

  return combinedHandlers
}

// 默认导出
export default {
  useSwipe,
  usePinch,
  useLongPress,
  useDoubleTap,
  useDrag,
  useGestures,
}

